/*
 * funcionesPFS.c
 *
 *  Created on: 25/09/2011
 *      Author: utn_so
 */

#include "main.h"
void setearCfgPFS(char **pPuerto,char **pDirIp,char **pmiPuerto)
{
  char tokenPuerto[] ="Puerto Destino";
  char miPuerto[] = "Puerto";
  char tokenDirIp[] = "Direccion Ip";
  int32_t leerCfg = 0;

  leerCfg = leerConfiguracion(pathCfg,tokenPuerto,pPuerto);
  leerCfg = leerConfiguracion(pathCfg,tokenDirIp,pDirIp);
  leerCfg = leerConfiguracion(pathCfg,miPuerto,pmiPuerto);

}
int16_t puertoANro (char *pPuerto)
{
	int32_t memoriaLiberada=0;
	int16_t puerto = atoi(pPuerto);
	memoriaLiberada = liberarMemoria(&pPuerto);
	return puerto;
}
void armarNombreLargo(stLongFileName stArchivosNombreLargo,char **nombreLargo)
{
	char** nombreCorto=NULL;
	uint32_t traduceOk;
	traduceOk = traducirArchivoNombreLargo(stArchivosNombreLargo.LFN_NombreParte1,nombreCorto,sizeof(stArchivosNombreLargo.LFN_NombreParte1));

	sprintf(*nombreLargo,"%s",*nombreCorto);
	traduceOk = traducirArchivoNombreLargo(stArchivosNombreLargo.LFN_NombreParte2,nombreCorto,sizeof(stArchivosNombreLargo.LFN_NombreParte2));
	sprintf(*nombreLargo,"%s%s",*nombreLargo,*nombreCorto);
	traduceOk = traducirArchivoNombreLargo(stArchivosNombreLargo.LFN_NombreParte3,nombreCorto,sizeof(stArchivosNombreLargo.LFN_NombreParte3));
	sprintf(*nombreLargo,"%s%s",*nombreLargo,*nombreCorto);

	free(*nombreCorto);

}
uint32_t traducirArchivoNombreLargo(uint16_t *archNombreLargo,char **nombreCorto,int8_t largoArchivo)
{
	uint32_t tamNombreCorto=0;
	*nombreCorto = (char *)calloc((largoArchivo/2),sizeof(char));
	unicode_utf16_to_utf8_inbuffer(archNombreLargo, largoArchivo, *nombreCorto,&tamNombreCorto);


	return tamNombreCorto;
}

/* Funcion Para Traducir De UTF16 a UTF 8 */
int16_t unicode_utf16_to_utf8_inbuffer(const uint16_t *src_utf16, const size_t src_utf16size, char* dest_utf8, size_t *dest_utf8size) {
	UErrorCode error = U_ZERO_ERROR;

	u_strToUTF8(dest_utf8, src_utf16size + 1, dest_utf8size, src_utf16, src_utf16size, &error);

	if (error != U_ZERO_ERROR) {
		return 0;
	}

	return 1;
}

int32_t* leerFatRegion ()
{
		extern stBootSector sectorBoot;
		int32_t cantBytes = 4;
		int32_t cantClusters = TAMSECTOR / cantBytes * sectorBoot.BPB_FATSz32;
		int32_t *vecDeClusters;
		int32_t sectoresLeidos=0;
		int32_t clusterAlmacenado=0;
		int32_t acumulador=0;
		char* sector;
		sector = (char*) calloc (TAMSECTOR, sizeof(char));
		vecDeClusters = (int32_t*) calloc (cantClusters, sizeof(int32_t)); /* --> Ocupa 0.5 MB en memoria */

		while (sectoresLeidos<sectorBoot.BPB_FATSz32)
		{
		/*	leerSector (archivoMapeado, sectorBoot.BPB_RsvdSecCnt + sectoresLeidos, sector); Send Disco*/

			while (acumulador<TAMSECTOR)
			{
				memcpy (vecDeClusters + clusterAlmacenado, sector + acumulador, cantBytes);
				clusterAlmacenado++;
				acumulador += cantBytes;
			}
			clusterAlmacenado=0;
			sectoresLeidos++;
		}
		free(sector);
		return vecDeClusters;
}

int32_t agregarNClustersLibres(int32_t *clustersLibres, int32_t *numerosDeClusters, int32_t n)
{
	int32_t i=0;
	while(i<n)
	{
		clustersLibres = clustersLibres + i;
		numerosDeClusters = numerosDeClusters + i;
		agregarClusterLibre(&clustersLibres,*numerosDeClusters);
		i++;
	}
	return Retorno_OK;
}

int32_t agregarClusterLibre(int32_t **clustersLibres, int32_t numeroDeCluster)
{
	*clustersLibres[numeroDeCluster] = (int32_t) 0;

	return Retorno_OK;
}

int32_t *removerNClusters(int32_t *clustersLibres, int32_t n, int32_t cantClusterTotal)
{
	int32_t nroCluster=0;
	int32_t *clusterLibre;
	clusterLibre = (int32_t *)calloc(n,sizeof(int32_t));
	int32_t cantClustersLibres = 0;
	while (nroCluster < cantClusterTotal && cantClustersLibres < n )
	{
		if (clustersLibres[nroCluster] == 0 )
				{
				clusterLibre[cantClustersLibres] = removerCluster(clustersLibres);
				cantClustersLibres++;
				}
		nroCluster++;
	}
	return clusterLibre;
}

int32_t removerCluster(int32_t *clustersLibres)
{

	int32_t clusterDisponible;
	clusterDisponible = *clustersLibres;

	return clusterDisponible;
}

int32_t obtenerClusterSiguiente (int32_t *vecDeClusters,int32_t clusterActual)
{
	int32_t clusterARetornar;
	clusterARetornar = vecDeClusters[clusterActual];
	if (clusterARetornar != FINARCHIVO)
		return clusterARetornar;
	return FINARCHIVO;
}

/*TODO . Lo que hace hasta ahora es almacenar de acuerdo al tipo de estructura (lfn o no lfn)
 * cada 32 bytes lo del primer sector del primer cluster del directorio raiz, pero se pisan */



int32_t buscarEntrada(char *entradaABuscar,int32_t clusterEntrada) /*Devuelve el nro de Cluster de la entrada buscada */
{
	extern stBootSector sectorBoot;
	stLongFileName stArchivosNombreLargo;
	stDirectoryTable stEntradasDeDirectorio;
	int32_t cantLeido = 0;
	int8_t cantALeer = 32;
	int8_t atrib;
	int8_t nroSectorDelClust=0;
	int8_t entradaEncontrada=0;
	int32_t nroClusterEncontrado=0;
	char *nombreLargo;
	nombreLargo = (char *)calloc(13,sizeof(char));
	/* Leo y Recibo El Cluster pasado (El primero es Raiz), lo almaceno en sectoresDelClus Para Empezar a buscar mi cadena */
	char **sectoresDelClus; /*-----> Llenar */
	/**************************/
	while (nroSectorDelClust < sectorBoot.BPB_SecPerClus && entradaEncontrada == 0)
		{
				while(cantLeido < TAMSECTOR && entradaEncontrada == 0)
				{
					memcpy(&atrib,sectoresDelClus[nroSectorDelClust],sizeof(int8_t));
					if (atrib == 0x0F)
					{
						memcpy(&stArchivosNombreLargo,sectoresDelClus[nroSectorDelClust],cantLeido + cantALeer);
						cantLeido +=cantALeer;
						memcpy(&stEntradasDeDirectorio,sectoresDelClus[nroSectorDelClust],cantLeido +cantALeer);
						armarNombreLargo(stArchivosNombreLargo,&nombreLargo);
					}	else
						memcpy(&stEntradasDeDirectorio,sectoresDelClus[nroSectorDelClust],cantLeido +cantALeer);
						cantLeido +=cantALeer;
					if((char *)stEntradasDeDirectorio.DT_FileName == entradaABuscar || nombreLargo == entradaABuscar)
					{
						entradaEncontrada =1;
						char *entrada;
						entrada = (char *)calloc(2,sizeof(int16_t));
						sprintf(entrada,"%d%d",stEntradasDeDirectorio.DT_ClusterInicialLow,stEntradasDeDirectorio.DT_ClusterInicialHigh);
						nroClusterEncontrado = atoi(entrada);
					}
				}

		}
	return nroClusterEncontrado;
}
int32_t leerSubDirectorios (char *entradaABuscar)
{
	extern stBootSector sectorBoot;
	char *spTokenSafe;
	char *palabra;
	int32_t clusterEntrada = sectorBoot.BPB_RootClus;
	palabra = strtok_r(entradaABuscar,"/",&spTokenSafe);
	while (palabra != NULL)
	{
		if((strcmp(palabra,"/"))==0) /* ----> Quiero Listar El Directorio Raiz, Ya tengo el Nro de Cluster entonces lo devuelvo */
			return clusterEntrada;
		clusterEntrada = buscarEntrada(palabra,clusterEntrada);
		palabra=strtok_r(NULL,"/",&spTokenSafe);
	}
return clusterEntrada;
}
/* Cuando Ya tengo la localizacion del Archivo o Directorio llamo a leerEntrada y Obtengo el contenido real */
void leerEntrada(int32_t nroCluster, char **sectores)
{
	extern stBootSector sectorBoot;
	int32_t *sectoresDelClus;
	sectoresDelClus = deClusterASectores (nroCluster);

	/* ----> Envio Al Disco los N pedidos de Sectores */
	 /* char **sectores  Aca Voy A Guardar Todos los sectores que forman el bloque/cluster */
	/* ----> Recibo la Respuesta Del Disco Armo El Bloque */


}
